(defvar kill-buffer-name-list '("*NeoTree*") "When buffer name in list,kill the buffer not window.")
(defun quit-window-or-buffer()
  (interactive)
  (require 'subr-x)
  (if (> (count-windows) 1)
	  (if (member (string-trim (buffer-name)) kill-buffer-name-list)
		  (kill-this-buffer)
		(delete-window))
	(kill-this-buffer)))

(defun my-save-as-with-time()
  (interactive)
  (require 'subr-x)
  (let* ((file-extention "txt")
		 ;;(file-extention (if (string-blank-p insert-extension) "md" insert-extension))
		 (now-time (format-time-string "%H%M"))
		 (current-line-string (buffer-substring-no-properties (line-beginning-position) (line-end-position)))
		 (remove-char-this-line (replace-regexp-in-string "[:<>?？!！]+" "" current-line-string))
		 (trim-this-line (string-trim remove-char-this-line))
		 (replace-this-line (replace-regexp-in-string "[:*<>,，\n\t ]+" "_" trim-this-line))
		 (now-save-file-name (if (string-blank-p current-line-string)
								 (format "%s_%s_%s.%s" (format-time-string "%Y%m%d") (format-time-string "%H%M") (format-time-string "%S%3N") file-extention)
							   (format "%s_%s_%s.%s" (format-time-string "%Y%m%d") (format-time-string "%H%M") replace-this-line file-extention)))
		 (now-save-full-name (concat (file-name-as-directory default-directory) now-save-file-name))
		 (now-modified-full-name (read-file-name "Write file: " now-save-full-name)))
	(write-file now-modified-full-name)
	(message (format "File save as [%s]" now-modified-full-name))))


(defun xah-new-empty-buffer ()
    "Create a new empty buffer.
Version 2017-11-01"
	(interactive)
	(let (($buf (generate-new-buffer (format "%s%s" "untitled_" (format-time-string "%m%d_%H%M")))))
	  (switch-to-buffer $buf)
	  (funcall 'text-mode)
	  (setq buffer-offer-save t)
	  $buf
	  ))

(defun revert-buffer-with-gbk ()
  (interactive)
  (revert-buffer-with-coding-system 'gbk))

(defun myrename-file-and-buffer (new-name)
  "Renames both current buffer and file it's visiting to NEW-NAME."
  (interactive (list (read-string "New name:" (buffer-name))))
  (let ((name (buffer-name))
		(filename (buffer-file-name)))
	(if (not filename)
		(message "Buffer '%s' is not visiting a file!" name)
	  (if (get-buffer new-name)
		  (message "A buffer named '%s' already exists!" new-name)
		(progn
		  (rename-file filename new-name 1)
		  (rename-buffer new-name)
		  (set-visited-file-name new-name)
		  (set-buffer-modified-p nil))))))


(defun xah-open-file-at-cursor ()
  "Open the file path under cursor.
If there is text selection, uses the text selection for path.
If the path starts with “http://”, open the URL in browser.
Input path can be {relative, full path, URL}.
Path may have a trailing “:‹n›” that indicates line number. If so, jump to that line number.
If path does not have a file extension, automatically try with “.el” for elisp files.
This command is similar to `find-file-at-point' but without prompting for confirmation.

URL `http://ergoemacs.org/emacs/emacs_open_file_path_fast.html'
Version 2018-02-21"
  (interactive)
  (let* (($inputStr (if (use-region-p)
                        (buffer-substring-no-properties (region-beginning) (region-end))
                      (let ($p0 $p1 $p2
                                ;; chars that are likely to be delimiters of file path or url, e.g. space, tabs, brakets. The colon is a problem. cuz it's in url, but not in file name. Don't want to use just space as delimiter because path or url are often in brackets or quotes as in markdown or html
                                ($pathStops "^  \t\n\"`'‘’“”|()[]{}「」<>〔〕〈〉《》【】〖〗«»‹›❮❯❬❭·。\\"))
                        (setq $p0 (point))
                        (skip-chars-backward $pathStops)
                        (setq $p1 (point))
                        (goto-char $p0)
                        (skip-chars-forward $pathStops)
                        (setq $p2 (point))
                        (goto-char $p0)
                        (buffer-substring-no-properties $p1 $p2))))
         ($path
          (replace-regexp-in-string
           "^file:///" "/"
           (replace-regexp-in-string
            ":\\'" "" $inputStr))))
    (if (string-match-p "\\`https?://" $path)
        (if (fboundp 'xahsite-url-to-filepath)
            (let (($x (xahsite-url-to-filepath $path)))
              (if (string-match "^http" $x )
                  (browse-url $x)
                (find-file $x)))
          (progn (browse-url $path)))
      (if ; not starting “http://”
          (string-match "^\\`\\(.+?\\):\\([0-9]+\\)\\'" $path)
          (let (
                ($fpath (match-string 1 $path))
                ($line-num (string-to-number (match-string 2 $path))))
            (if (file-exists-p $fpath)
                (progn
		  (if (bound-and-true-p view-mode)
		      (view-file $fpath)
		      (find-file $fpath))
                  (goto-char 1)
                  (forward-line (1- $line-num)))
              (when (y-or-n-p (format "file no exist: 「%s」. Create?" $fpath))
                (find-file $fpath))))
        (if (file-exists-p $path)
            (progn ; open f.ts instead of f.js
              (let (($ext (file-name-extension $path))
                    ($fnamecore (file-name-sans-extension $path)))
                (if (and (string-equal $ext "js")
                         (file-exists-p (concat $fnamecore ".ts")))
		    (if (bound-and-true-p view-mode)
			(view-file (concat $fnamecore ".ts"))
		      (find-file (concat $fnamecore ".ts")))
                  (if (bound-and-true-p view-mode)
		  (view-file $path)
		(find-file $path)))))
          (if (file-exists-p (concat $path ".el"))
              (find-file (concat $path ".el"))
            (when (y-or-n-p (format "file no exist: 「%s」. Create?" $path))
	      (if (bound-and-true-p view-mode)
		  (view-file $path)
		(find-file $path))
              )))))))

(defun xah-copy-file-path (&optional @dir-path-only-p)
  "Copy the current buffer's file path or dired path to `kill-ring'.
Result is full path.
If `universal-argument' is called first, copy only the dir path.

If in dired, copy the file/dir cursor is on, or marked files.

If a buffer is not file and not dired, copy value of `default-directory' (which is usually the “current” dir when that buffer was created)

URL `http://ergoemacs.org/emacs/emacs_copy_file_path.html'
Version 2017-09-01"
  (interactive "P")
  (let (($fpath
         (if (string-equal major-mode 'dired-mode)
             (progn
               (let (($result (mapconcat 'identity (dired-get-marked-files) "\n")))
                 (if (equal (length $result) 0)
                     (progn default-directory )
                   (progn $result))))
           (if (buffer-file-name)
               (buffer-file-name)
             (expand-file-name default-directory)))))
    (kill-new
     (if @dir-path-only-p
         (progn
           (message "Directory path copied: 「%s」" (file-name-directory $fpath))
           (file-name-directory $fpath))
       (progn
         (message "File path copied: 「%s」" $fpath)
         $fpath )))))


(provide 'edit-init)
